package com.demo.utils;

import com.demo.core.Constants;

import java.math.BigDecimal;
import java.security.SecureRandom;
import java.sql.SQLException;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * 数值、字符串运算
 *
 * @author Anthony
 */
public class ToolUtils {

    private static String[] chars = new String[]{"0", "1", "2", "3", "4", "5",
            "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I",
            "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
            "W", "X", "Y", "Z"};
    private static Pattern positivePattern = Pattern.compile("[0-9]+");
    private static Pattern floatPattern = Pattern.compile("[0-9.]+");
    private static Pattern distancePattern = Pattern.compile("([0-9.]+)(公里|km|千米|空距){1}");
    private static Pattern distanceZhPattern = Pattern.compile("([一二三四五六七八九十百点]+)(公里|km|千米|空距){1}");

    public static boolean ltZero(BigDecimal a) {
        if (a == null)
            return true;
        return a.compareTo(new BigDecimal(0)) < 0;
    }

    public static boolean isZero(BigDecimal a) {
        if (a == null)
            return true;
        return a.compareTo(new BigDecimal(0)) <= 0;
    }

    public static boolean gtZero(BigDecimal a) {
        if (a == null)
            return true;
        return a.compareTo(new BigDecimal(0)) > 0;
    }

    public static BigDecimal add(BigDecimal a, BigDecimal b) {
        if (a == null) {
            if (b == null)
                return new BigDecimal(0);
            else
                return b;
        } else {
            if (b == null)
                return a;
            else
                return a.add(b).setScale(18, BigDecimal.ROUND_HALF_EVEN);
        }
    }

    public static BigDecimal add(BigDecimal a, BigDecimal b, BigDecimal c) {
        return add(add(a, b), c);
    }

    public static BigDecimal subtract(BigDecimal a, BigDecimal b) {
        if (a == null) {
            if (b == null)
                return new BigDecimal(0);
            else
                return b.multiply(new BigDecimal(-1)).setScale(18, BigDecimal.ROUND_HALF_EVEN);
        } else {
            if (b == null)
                return a;
            else
                return a.subtract(b).setScale(18, BigDecimal.ROUND_HALF_EVEN);
        }
    }

    public static BigDecimal subtract(BigDecimal a, BigDecimal b, BigDecimal c) {
        return subtract(subtract(a, b), c);
    }

    public static BigDecimal multiply(BigDecimal a, BigDecimal b) {
        if (a == null) {
            return new BigDecimal(0);
        } else {
            if (b == null)
                return new BigDecimal(0);
            else
                return a.multiply(b).setScale(18, BigDecimal.ROUND_HALF_EVEN);
        }
    }

    public static BigDecimal divide(BigDecimal a, BigDecimal b) {
        if (a == null) {
            return new BigDecimal(0);
        } else {
            if (b == null || b.compareTo(new BigDecimal(0)) == 0)
                return new BigDecimal(0);
            else
                return a.divide(b, 18, BigDecimal.ROUND_HALF_EVEN);
        }
    }

    public static String format(BigDecimal a) {
        if (a == null)
            return "";
        return a.setScale(8, BigDecimal.ROUND_HALF_EVEN).toPlainString();
    }

    /**
     * 将两个数值字符串求和
     *
     * @param str1
     * @param str2
     * @param Rnd
     * @return
     */
    public static String addString(String str1, String str2, int Rnd) {
        if (str1 == null || str2 == null) {
            return "";
        }
        String added = "";
        try {
            BigDecimal val1 = new BigDecimal(str1);
            BigDecimal val2 = new BigDecimal(str2);
            added = val1.add(val2).setScale(Rnd, BigDecimal.ROUND_HALF_UP)
                    .toString();
        } catch (NumberFormatException nfe) {
        }
        return added;
    }

    /**
     * 将两个数值字符串相减
     *
     * @param str1
     * @param str2
     * @param Rnd
     * @return
     */
    public static String subString(String str1, String str2, int Rnd) {
        if (str1 == null || str2 == null) {
            return "";
        }
        String added = "";
        try {
            BigDecimal val1 = new BigDecimal(str1);
            BigDecimal val2 = new BigDecimal(str2);
            added = val1.subtract(val2).setScale(Rnd, BigDecimal.ROUND_HALF_UP)
                    .toString();
        } catch (NumberFormatException nfe) {
        }
        return added;
    }

    /**
     * 将两个数值字符串相乘
     *
     * @param str1
     * @param str2
     * @param Rnd
     * @return
     */
    public static String multiString(String str1, String str2, int Rnd) {
        if (str1 == null || str2 == null) {
            return "";
        }
        String added = "";
        try {
            BigDecimal val1 = new BigDecimal(str1);
            BigDecimal val2 = new BigDecimal(str2);
            added = val1.multiply(val2).setScale(Rnd, BigDecimal.ROUND_HALF_UP)
                    .toString();
        } catch (NumberFormatException nfe) {
        }
        return added;
    }

    /**
     * 将两个数值字符串相除
     *
     * @param str1
     * @param str2
     * @param Rnd
     * @return
     */
    public static String divideString(String str1, String str2, int Rnd) {
        if (str1 == null || str2 == null) {
            return "";
        }
        String added = "";
        try {
            BigDecimal val1 = new BigDecimal(str1);
            BigDecimal val2 = new BigDecimal(str2);
            added = val1.divide(val2, Rnd, BigDecimal.ROUND_HALF_UP).toString();
        } catch (NumberFormatException nfe) {
        }
        return added;
    }

    public static String divideString(String str1, String str2, int Rnd,
                                      int round) {
        if (str1 == null || str2 == null) {
            return "";
        }
        String added = "";
        try {
            BigDecimal val1 = new BigDecimal(str1);
            BigDecimal val2 = new BigDecimal(str2);
            added = val1.divide(val2, Rnd, round).toString();
        } catch (NumberFormatException nfe) {
        }
        return added;
    }

    /**
     * 比较数值字符串
     *
     * @param str1
     * @param str2
     * @return
     */
    public static int compareString(String str1, String str2) {
        try {
            BigDecimal bd1 = null;
            BigDecimal bd2 = null;
            try {
                bd1 = new BigDecimal(str1);
            } catch (Exception ex) {
                return -1;
            }
            try {
                bd2 = new BigDecimal(str2);
            } catch (Exception ex) {
                return 1;
            }
            return bd1.compareTo(bd2);
        } catch (Exception ex) {
            return 0;
        }
    }

    /**
     * 格式化数字 9999999 -> 9,999,999
     *
     * @param input
     * @return
     */
    public static String formatNumber(String input) {
        if (input == null || input.trim().length() == 0) {
            return "0";
        }
        boolean neg = input.startsWith("-");
        input = neg ? input.substring(1).trim() : input.trim();
        int point = (input.indexOf(".") > 0) ? input.indexOf(".") : input
                .length();

        StringBuffer result = new StringBuffer();
        for (int i = 0; i < point - 1; i++) {
            if ((point - i - 1) % 3 == 0) {
                result.append(input.charAt(i)).append(",");
            } else {
                result.append(input.charAt(i));
            }
        }
        result.append(input.substring(point - 1));
        return neg ? "-" + result.toString() : result.toString();
    }

    /**
     * 格式化数字 9999999.9999 -> 9,999,999.9999
     *
     * @param input
     * @param dec
     * @return
     */
    public static String formatDecNum(String input, int dec) {
        if (input == null || input.trim().length() == 0) {
            return "0";
        }
        int point = input.indexOf(".");
        String result = formatNumber(input.substring(0,
                (point == -1) ? input.length() : point));
        if (dec == 0) {
            return result;
        }
        String decstr = (point == -1) ? "" : input.substring(point + 1);
        while (decstr.length() < dec) {
            decstr = decstr + "0";
        }
        return (result + "." + decstr.substring(0, dec));
    }

    /**
     * 在前面补sAppend，形成定长的字符串
     *
     * @param sOld
     * @param sAppend
     * @param remainLen
     * @return
     */
    public static String strAppend(String sOld, String sAppend, int remainLen) {
        String sNew = sAppend + sOld;
        return sNew.substring(sNew.length() - remainLen);
    }

    /**
     * 转成HTML字符串，如'<','>','\n'
     *
     * @param sIn
     * @return
     */
    public static String toHTMLStr(String sIn) {
        if (sIn == null) {
            return sIn;
        }
        sIn = sIn.replace("<", "&lt;");
        sIn = sIn.replace(">", "&gt;");
        sIn = sIn.replace(Constants.LINE_SEPERATOR, "<br>");
        return sIn;
    }

    /**
     * 判断字符串是否为double数字
     *
     * @param str
     * @return
     */
    public static boolean isDouble(String str) {
        Pattern pattern = Pattern
                .compile("^[-+]?(\\d+(\\.\\d*)?|\\.\\d+)([eE]([-+]?([012]?\\d{1,2}|30[0-7])|-3([01]?[4-9]|[012]?[0-3])))?[dD]?$");
        return pattern.matcher(str).matches();
    }

    public static boolean isNumber(String str) {
        Pattern pattern = Pattern.compile("[0-9.]+");
        return pattern.matcher(str).matches();
    }

    /**
     * 计算以base为底的对数
     *
     * @param value
     * @param base
     * @return
     */
    public static double log(double value, double base) {
        return Math.log(value) / Math.log(base);
    }

    public static double round(double value, int scale, int roundingMode) {
        BigDecimal bd = new BigDecimal(value);
        bd = bd.setScale(scale, roundingMode);
        return bd.doubleValue();
    }

    public static double round(double value, int scale) {
        BigDecimal bd = new BigDecimal(value);
        bd = bd.setScale(scale, BigDecimal.ROUND_HALF_UP);
        return bd.doubleValue();
    }

    /**
     * 字符串反转
     *
     * @param str
     * @return
     */
    public static String reverseString(String str) {
        StringBuffer sb = new StringBuffer();
        for (int i = str.length() - 1; i >= 0; i--) {
            sb.append(str.charAt(i));
        }
        return sb.toString();
    }

    /**
     * 字符串反转，时间复杂度O(n)，空间复杂度O(1)
     *
     * @param letters
     * @param begin
     * @param end
     * @return
     */
    private static String reverseString(char[] letters, int begin, int end) {
        if (begin >= end) {
            return null;
        }
        for (int i = begin, j = end; i < j; i++, j--) {
            char tmp = letters[i];
            letters[i] = letters[j];
            letters[j] = tmp;
        }
        return new String(letters);
    }

    /**
     * 左旋转字符串，abcdef->ab.cdef->ba.fedc->cdefab
     *
     * @param str
     * @param n   旋转的位数
     * @return
     */
    public static String leftRotateString(String str, int n) {
        if (str == null || str.length() == 0) {
            return str;
        }
        if (n <= 0 || n >= str.length()) {
            return str;
        }
        int begin = 0;
        int end = str.length() - 1;
        char[] letters = str.toCharArray();
        reverseString(letters, begin, n - 1);
        reverseString(letters, n, end);
        reverseString(letters, begin, end);
        return new String(letters);
    }

    /**
     * 字符串是否包含问题的“最好的方法”，时间复杂度O(n + m)，空间复杂度O(1)
     *
     * @param a 比b长
     * @param b 判断b是否为a的真子集
     * @return
     */
    public static boolean comtain(char[] a, char[] b) {
        int hash = 0;
        for (int i = 0; i < a.length; ++i)
            hash |= (1 << (a[i] - 'A'));
        for (int i = 0; i < b.length; ++i) {
            if ((hash & (1 << (b[i] - 'A'))) == 0)
                return false;
        }
        return true;
    }

    public static String genShortUUID() {
        StringBuffer shortBuffer = new StringBuffer();
        String uuid = UUID.randomUUID().toString().replace("-", "");
        for (int i = 0; i < 8; i++) {
            String str = uuid.substring(i * 4, i * 4 + 4);
            int x = Integer.parseInt(str, 16);
            shortBuffer.append(chars[x % 36]);
        }
        return shortBuffer.toString().toUpperCase();
    }

    public static int parsePositive(String str) {
        if (str == null)
            return 0;
        Matcher matcher = positivePattern.matcher(str);
        if (matcher.find())
            return Integer.parseInt(matcher.group(0));
        return 0;
    }

    public static float parseFloat(String str) {
        if (str == null)
            return 0;
        Matcher matcher = floatPattern.matcher(str);
        if (matcher.find())
            return Float.parseFloat(matcher.group(0));
        return 0;
    }

    public static float parseDistance(String str) {
        if (str == null)
            return 0;
        str = str.replaceAll(" ", "").toLowerCase();
        Matcher matcher = distancePattern.matcher(str);
        if (matcher.find())
            return Float.parseFloat(matcher.group(1));
        Matcher matcherzh = distanceZhPattern.matcher(str);
        if (matcherzh.find())
            return toNumber(matcherzh.group(1));
        return 0;
    }

    private static float toNumber(String str) {
        String left = str;
        int k = str.indexOf("点");
        if (k > -1)
            left = str.substring(0, k);
        if (left.endsWith("十"))
            left = left + "0";
        if (k > -1)
            str = left + str.substring(k);
        else
            str = left;
        str = str.replaceAll("万|千|百|十", "");
        str = str.replace("点", ".");
        str = str.replace("一", "1");
        str = str.replace("二", "2");
        str = str.replace("三", "3");
        str = str.replace("四", "4");
        str = str.replace("五", "5");
        str = str.replace("六", "6");
        str = str.replace("七", "7");
        str = str.replace("八", "8");
        str = str.replace("九", "9");
        return Float.parseFloat(str);
    }

    public static void main(String[] args) throws SQLException, ClassNotFoundException {
//        SysConfig.out(log(10, 2));
//        SysConfig.out(isNumber("120.01"));

//        Connection conn = DBManager.mysql("106.14.124.228", "gugu", "root", "Gugu2019!");
//        String sql = "select id,racename from t_race where webid=1";
//        ResultSet rs = DBManager.query(conn, sql);
//        while (rs.next()) {
//            String id = rs.getString(1);
//            String racename = rs.getString(2);
////            SysConfig.out(racename + " = " + parseDistance(racename));
//            DBManager.update(conn, "update t_race set sfdistance=" + parseDistance(racename) + " where id=" + id);
//        }
//        DBManager.close(conn);

//        SysConfig.out(parseDistance("3月13日三次点三十公里训放"));
    }
}
